#include "kstdio.h"
#include "astralapi.h"

char sbf_system_out[4096];

static int exec_full(SysBuffer sbf);
static int exec_empty(SysBuffer sbf);

static struct SysBuffer global_stdout =
{
    .buff = sbf_system_out,
    .ptr = 0,
    .size = 4096,
    .full_handle = CAST_AS(runable, exec_full),
    .empty_handle = CAST_AS(runable, exec_empty),
};

static int exec_full(SysBuffer sbf)
{
    int actual;


    static AstralDevice dev2 = NULL;
    if (!dev2)
    {
        dev2 = open_device("terminal");
    }
    if(dev2)
    {
        dev2->operations->dwrite(dev2, sbf->buff, sbf->size, &actual);
    }

    static AstralDevice dev = NULL;
    if (!dev)
    {
        dev = open_device("tty0");
    }
    if (dev)
    {

        dev->operations->dwrite(dev, sbf->buff, sbf->size, &actual);
    }
    return actual;
}

static int exec_empty(SysBuffer sbf)
{
    return 0;
}

void write_to_kstdout(const char *buff, int size, int *actual)
{
    int real_cnt = 0;
    boolean status;
    for (int i = 0; *buff && (i < size); i++, buff++)
    {
        if (*buff == '\n')
        {
            status = putc_buffer(&global_stdout, '\r');
        }
        status |= putc_buffer(&global_stdout, *buff);
        if (status)
        {
            real_cnt++;
        }
        else
        {
            break;
        }
    }
    if(actual)
    {
        *actual = real_cnt;
    }
}

void putc_to_kstdout(char c)
{
    putc_buffer(&global_stdout, c);
    flush_buffer(&global_stdout);
}


void flush_kstdout()
{
    flush_buffer(&global_stdout);
}